//
// Created by wujehy on 2020/6/25.
//

#include <iostream>
#include <thread>
#include <future>
#include "SharedClass.h"

/**
 * @brief　自己实现的
 * @return
 */

void TestFunc()
{
    SharedClass *obj = new SharedClass( 1, "test1" );
    std::shared_ptr<SharedClass> port_obj1( obj );
    std::cout << " port_obj1 , id = " << port_obj1->getId() << " name  = " << port_obj1->getName() << " count = "
              << port_obj1.use_count() << std::endl;
    // 获取
    std::shared_ptr<SharedClass> port_obj2( obj->getMySelf());
    std::cout << " port_obj1 , id = " << port_obj1->getId() << " name  = " << port_obj1->getName() << " count = "
              << port_obj1.use_count() << std::endl;
    std::cout << " port_obj2 , id = " << port_obj2->getId() << " name  = " << port_obj2->getName() << " count = "
              << port_obj2.use_count() << std::endl;
}

class TestDataType
{
public:
    TestDataType(int id, const std::string &name) : id( id ), name( name )
    {
        std::cout << " init TestDataType id = " << this->id << " name = " << this->name << std::endl;
    }

    virtual ~TestDataType()
    {
        std::cout << " delete TestDataType id = " << this->id << " name = " << this->name << std::endl;

    }

    int getId() const
    {
        return id;
    }

    const std::string &getName() const
    {
        return name;
    }

    void setName(const std::string &name)
    {
        TestDataType::name = name;
    }

    // 测试 返回自身的指针　
    std::shared_ptr<TestDataType> getMySelf()
    {
        return std::shared_ptr<TestDataType>( this );
    }

private:
    int id;
    std::string name;
};

void TestFunc2()
{
    std::cout << std::endl << std::endl << " shared_ptr Test start " << std::endl;
    TestDataType *obj = new TestDataType( 2, "test2" );
    std::shared_ptr<TestDataType> port_obj1( obj );
    std::cout << " port_obj1 , id = " << port_obj1->getId() << " name  = " << port_obj1->getName() << " count = "
              << port_obj1.use_count() << std::endl;
//  吧这里的注释打开就能看到　错误了
//    std::shared_ptr<TestDataType> port_obj2(obj->getMySelf());
//    std::cout << " port_obj1 , id = " << port_obj1->getId() << " name  = " << port_obj1->getName() <<" count = " << port_obj1.use_count()<< std::endl;
//    std::cout << " port_obj2 , id = " << port_obj2->getId() << " name  = " << port_obj2->getName() << " count = " << port_obj2.use_count() << std::endl;

    std::cout << " TestFunc2 endl " << std::endl;
}

/**
 * @brief　这里的高级用法是　shared_ptr　共同指向一个对象的地址的时候存在的问题
 * 每个　shared_ptr　对象　都记录了他们自身的计数　，
 * 　但是释放的时候　多个智能指针对象　释放同一个地址　
 * 就会导致　重复释放的问题　
 * TestFunc() 使用自己实现的　getMySelf　返回　自身　，计数器增加了　
 *
 * 但是　TestFunc2　无法就会存在　计数混乱的问题　，　析构重复导致程序崩溃
 *
 *　主要用在异步多线程的时候　
 *
 * @return
 */
int main()
{

    TestFunc();

    TestFunc2();
    return 0;
}